#include <vector>
#include <string.h>
#include <QDir>
#include "clcomfuncs.h"
#include "SelfFormartFile.h"

void Encrypt(const char* content, int nContentsize, string& outEncryptStr);
void DEncrypt(string& inStr, char** outContent, int& outsize);

CSelfFormartFile::CSelfFormartFile(
        const char* filename,
        string id,
        bool bCreate)
{
    m_file.setFileName(filename);

    m_bEncrypt = false;
	m_strID = id;

    m_bReadOver = false;

    manualOpen(bCreate);
}
void CSelfFormartFile::manualOpen(bool bCreate)
{
    if (!BFileValid() && bCreate)
    {
        AppendWriteFile(nullptr, 0);
    }
}

CSelfFormartFile::~CSelfFormartFile()
{
    if (m_file.isOpen())
	{
        m_file.close();
	}
}

void CSelfFormartFile::CloseFile()
{
    if (m_file.isOpen())
    {
        m_file.close();
    }
    m_bReadOver = false;
}
string CSelfFormartFile::GetID()
{
	return m_strID;
}

bool CSelfFormartFile::BFileValid()
{
    if (m_file.isOpen())
	{
        return true;
    }
    return QFile::exists(m_file.fileName());
}
bool CSelfFormartFile::ReadOver()
{
    return m_bReadOver;
}
int CSelfFormartFile::ReadFile(void* readContent, int contentLen)
{
    if (!m_file.isOpen())
	{
        m_file.open(QIODevice::ReadWrite);
        if (!m_file.isOpen())
		{
            return false;
		}
	}
	if (ReadOver())
	{
        m_file.close();
        return false;
	}
    char* p = (char*)readContent;
    qint64 nreadsize = m_file.read(p, contentLen);
    if (nreadsize < contentLen)
    {
        m_bReadOver = true;
    }
	if (m_bEncrypt)
	{
		string tempstr = (char*)readContent;
		char* p = NULL;
		int nOutsize = 0;
		DEncrypt(tempstr, &p, nOutsize);

        memset(readContent, 0, contentLen);

		memcpy(readContent, (void*)p, nOutsize);

        delete[] p;
        p = nullptr;
	}
	return (int)nreadsize;
}
int CSelfFormartFile::ReadLine(void* readcontent, int contentLen)
{
    if (!m_file.isOpen())
    {
        m_file.open(QIODevice::ReadWrite);
        if (!m_file.isOpen())
        {
            return false;
        }
    }
    if (ReadOver())
    {
        m_file.close();
        return false;
    }
    char* p = (char*)readcontent;
    qint64 nreadsize = m_file.readLine(p, contentLen);
    if (nreadsize <= 0)
    {
        m_bReadOver = true;
    }
    if (m_bEncrypt)
    {
        string tempstr = (char*)readcontent;
        char* p = NULL;
        int nOutsize = 0;
        DEncrypt(tempstr, &p, nOutsize);

        memset(readcontent, 0, contentLen);

        memcpy(readcontent, (void*)p, nOutsize);

        delete[] p;
        p = nullptr;
    }
    return (int)nreadsize;
}

int CSelfFormartFile::RWriteFile(void* writeStr, int nWriteSize)
{
    m_file.remove();
    if (!m_file.isOpen())
    {
        m_file.open(QIODevice::ReadWrite);
        if (!m_file.isOpen())
        {
            return false;
        }
    }
    qint64 wsize = 0;
	if (m_bEncrypt)
	{
		string tempstr = "";
		Encrypt((char*)writeStr, nWriteSize, tempstr);

        wsize = m_file.write(tempstr.c_str(), tempstr.size());
	}
	else
	{
        wsize = m_file.write((char*)writeStr, nWriteSize);
	}
    return wsize;
}
int CSelfFormartFile::AppendWriteFile(void* writeStr, int nWriteSize)
{
    int wsize = 0;
    if (!m_file.isOpen())
	{
        m_file.open(QIODevice::ReadWrite);
        if (!m_file.isOpen())
        {
            return  -1;
        }
	}
    if (nWriteSize == 0)
    {
        return 0;
    }
	if (m_bEncrypt)
	{
		string tempstr = "";
		Encrypt((char*)writeStr, nWriteSize, tempstr);

        wsize = m_file.write(tempstr.c_str(), tempstr.size());
	}
	else
    {
        wsize = m_file.write((char*)writeStr, nWriteSize);
    }
    return wsize;
}

void CSelfFormartFile::SetEncrypt(bool bEncrypt)
{
	m_bEncrypt = bEncrypt;
}

void CSelfFormartFile::SetFileName(const char* filename)
{
    if (m_file.isOpen())
	{
        m_file.close();
	}
    m_file.setFileName(filename);
}
void CSelfFormartFile::GetFileName(char* outfilename, int nBuffersize)
{
    Q_UNUSED(nBuffersize);
    sprintf(outfilename, "%s", m_file.fileName().toLatin1().data());
}

int CSelfFormartFile::GetFileSize()
{
    if (!m_file.isOpen())
	{
        m_file.open(QIODevice::ReadWrite);
    }
    return m_file.size();
}

void Encrypt(const char* content, int nContentsize, string& outEncryptStr)
{
	outEncryptStr = "";
	char tempchars[8] = { 0 };
	for (int i = 0; i < nContentsize; ++i)
	{
        sprintf(tempchars, "%d", content[i]);
		if (outEncryptStr != "")
		{
			outEncryptStr += ",";
		}
		outEncryptStr += tempchars;
        memset(tempchars, 0, 8);
	}
}
void DEncrypt(string& inStr, char** outContent, int& outsize)
{
	std::vector<string> vNumbers;

    CLComFuncs::SplitString(&vNumbers, ",", inStr, false);
	outsize = (int)vNumbers.size();

	*outContent = new char[outsize];

    for (size_t i = 0; i < vNumbers.size(); ++i)
	{
		(*outContent)[i] = atoi(vNumbers[i].c_str());
	}
}
